package engine

import (
	"errors"
	"gitee.com/kinwyb/workflow/public"
	"gitee.com/kinwyb/workflow/storage"
)

// WorkFlowCreate 创建一个工作流
func WorkFlowCreate(flowID string, workFlowCode string, workFlowName string, ctx *public.ContextValue) (string, error) {
	_, err := storage.FlowQuery(flowID, ctx)
	if err != nil {
		return "", err
	}
	work := storage.WorkFlow{
		WorkFlowID:   public.IDGenIntString(),
		WorkFlowCode: workFlowCode,
		WorkFlowName: workFlowName,
		FlowID:       flowID,
		IsUse:        0,
	}
	err = storage.WorkFlowSave(work, ctx)
	if err != nil {
		return "", err
	}
	return work.WorkFlowID, nil
}

// WorkCreate 创建一个工作
func WorkCreate(req WorkCreateReq, ctx *public.ContextValue) (string, error) {
	work := storage.Work{
		WorkID:       public.IDGenIntString(),
		WorkFlowCode: req.WorkFlowCode,
		WorkName:     req.WorkName,
		ExtendVal1:   req.ExtendVal1,
		ExtendVal2:   req.ExtendVal2,
		ExtendVal3:   req.ExtendVal3,
		ExtendVal4:   req.ExtendVal4,
		ExtendVal5:   req.ExtendVal5,
		Data:         req.Data,
	}
	err := storage.WorkCreate(work, ctx)
	if err != nil {
		return "", err
	}
	workNode, _ := storage.ActiveWorkNodeQueryByWorkID(work.WorkID)
	if workNode != nil {
		_, err = WorkNodeDo(workNode.WorkDetailID, true, "", ctx)
		if err != nil {
			return work.WorkID, errors.New("工作创建成功,流程启动失败:" + err.Error())
		}
	}
	return work.WorkID, nil
}

// 工作判断节点执行
func workRouteDo(workNode *storage.WorkNode, ctx *public.ContextValue) (string, error) {
	if workNode.NodeType != int(NodeTypeRoute) {
		return "", nil
	}
	route, err := RouteQuery(workNode.RouteID)
	if err != nil {
		return "", err
	}
	isPass := routeParse(*route, workNode.Data)
	nextNodeID, err := storage.WorkNodeComplete(workNode, isPass, "自动", ctx)
	if err != nil {
		return "", err
	}
	if nextNodeID != "" {
		nextWorkNode, err := storage.WorkNodeQueryByID(nextNodeID, ctx)
		if err != nil {
			return "", err
		}
		if nextWorkNode.NodeType == int(NodeTypeRoute) {
			return workRouteDo(nextWorkNode, ctx)
		} else if nextWorkNode.NodeType == int(NodeTypeEnd) {
			// 连接的是结束节点，直接结束
			return WorkNodeDo(nextNodeID, true, "", ctx)
		}
	}
	return nextNodeID, nil
}

// WorkNodeDo 工作节点执行
func WorkNodeDo(workDetailID string, isPass bool, memo string, ctx *public.ContextValue) (string, error) {
	workNode, err := storage.WorkNodeQueryByID(workDetailID, ctx)
	if err != nil {
		return "", err
	}
	if workNode.NodeType == int(NodeTypeNormal) { //常规节点要判断权限
		hasPower := storage.NodeUserGroupCheckUser(workNode.NodeID, ctx.UserID, ctx)
		if !hasPower {
			return "", errors.New("无权执行该节点")
		}
	}
	nextNodeID, err := storage.WorkNodeComplete(workNode, isPass, memo, ctx)
	if err != nil {
		return "", err
	}
	if nextNodeID != "" {
		nextWorkNode, _ := storage.WorkNodeQueryByID(nextNodeID, ctx)
		if nextWorkNode != nil {
			if nextWorkNode.NodeType == int(NodeTypeRoute) {
				return workRouteDo(nextWorkNode, ctx)
			} else if nextWorkNode.NodeType == int(NodeTypeEnd) {
				return WorkNodeDo(nextNodeID, true, "", ctx)
			}
		}
	}
	return nextNodeID, nil
}

// WorkNodes 查询所有工作节点
func WorkNodes(workID string, ctx *public.ContextValue) ([]WorkNode, error) {
	nodes, err := storage.WorkNodes(workID, ctx)
	if err != nil {
		return nil, err
	}
	if len(nodes) < 1 {
		return nil, errors.New("未找到工作流信息")
	}
	var ret = make([]WorkNode, len(nodes))
	for i, v := range nodes {
		newNode := WorkNode{WorkNode: *v}
		if newNode.NodeType == int(NodeTypeRoute) {
			if newNode.RouteID == "" {
				newNode.RouteID = newNode.SRouteID
			}
			newNode.Route, _ = RouteQuery(newNode.RouteID)
		}
		ret[i] = newNode
	}
	return ret, nil
}

// EnableWorkFlow 启用工作流
func EnableWorkFlow(workFlowID string, ctx *public.ContextValue) error {
	return storage.EnableWorkFlow(workFlowID, ctx)
}

// DisableWorkFlow 禁用工作流
func DisableWorkFlow(workFlowID string, ctx *public.ContextValue) error {
	return storage.DisableWorkFlow(workFlowID, ctx)
}

// WaitDoWorkList 待工作列表
func WaitDoWorkList(workFlowCode string, userID string, ctx *public.ContextValue) ([]storage.WorkNode, error) {
	return storage.WaitDoWorkList(workFlowCode, userID, ctx)
}

// WorkFlowQuery 工作流查询,workFlowCode 工作流编码,useStatus 工作流状态(-1=全部,0=未启用,1=启用)
func WorkFlowQuery(workFlowID string, workFlowCode string, useStatus int, ctx *public.ContextValue) []*storage.WorkFlow {
	return storage.WorkFlowQuery(workFlowID, workFlowCode, useStatus, ctx)
}

// WorkNodeQueryByID 工作节点信息查询
func WorkNodeQueryByID(workDetailID string, ctx *public.ContextValue) (*storage.WorkNode, error) {
	return storage.WorkNodeQueryByID(workDetailID, ctx)
}

// WorkQueryByID 工作查询
func WorkQueryByID(workID string, ctx *public.ContextValue) (*storage.Work, error) {
	return storage.WorkQueryByID(workID, ctx)
}
